package analyzer

import (
	"fmt"
	"log/slog"
	"reflect"
	"st_data/internal/database"
	"strings"
)

// Analyzer 用于分析数据库表结构
type Analyzer struct {
	db *database.DB
}

// New 创建一个新的分析器
func New(db *database.DB) *Analyzer {
	return &Analyzer{db: db}
}

// FindDuplicateTables 查找结构相同的表
func (a *Analyzer) FindDuplicateTables() ([][]string, error) {
	tables, err := a.db.GetTables()
	if err != nil {
		return nil, err
	}

	// 存储表结构的映射
	structureMap := make(map[string][]string)

	// 分析每个表的结构
	for _, table := range tables {
		columns, err := a.db.GetTableStructure(table)
		if err != nil {
			return nil, err
		}

		// 将表结构转换为字符串表示
		structKey := a.getStructureKey(columns)
		structureMap[structKey] = append(structureMap[structKey], table)
	}

	// 找出重复的表
	var duplicates [][]string
	for _, tables := range structureMap {
		if len(tables) > 1 {
			duplicates = append(duplicates, tables)
		}
	}

	return duplicates, nil
}

// GetUniqueTablesWithoutDuplicates 获取去除重复后的唯一表列表
// 对于重复表，优先保留没有后缀标记的表
func (a *Analyzer) GetUniqueTablesWithoutDuplicates(duplicates [][]string) ([]string, error) {
	allTables, err := a.db.GetTables()
	if err != nil {
		return nil, err
	}

	// 创建一个映射来标记重复表
	duplicateMap := make(map[string]bool)

	// 对于每组重复表，选择最合适的表保留
	for _, group := range duplicates {
		if len(group) <= 1 {
			continue
		}

		// 找出最合适的表（没有后缀的表）
		bestTable := findBestTable(group)

		// 标记其他表为重复
		for _, table := range group {
			if table != bestTable {
				duplicateMap[table] = true
			}
		}
	}

	// 过滤掉重复的表
	var uniqueTables []string
	for _, table := range allTables {
		if !duplicateMap[table] {
			uniqueTables = append(uniqueTables, table)
		}
	}

	return uniqueTables, nil
}

// findBestTable 从一组重复表中找出最合适的表
// 优先选择没有后缀标记的表
func findBestTable(tables []string) string {
	if len(tables) == 0 {
		return ""
	}

	// 首先尝试找没有明显后缀的表
	for _, table := range tables {
		// 检查表名是否不包含常见的后缀标记
		if !hasCommonSuffix(table) {
			return table
		}
	}

	// 如果所有表都有后缀，则返回第一个表
	return tables[0]
}

// hasCommonSuffix 检查表名是否有常见的后缀标记
func hasCommonSuffix(tableName string) bool {
	commonSuffixes := []string{
		"_copy", "copy",
		"_20", "20", // 年份标记
		"_23", "23",
		"_24", "24",
		"_25", "25",
	}

	for _, suffix := range commonSuffixes {
		if strings.Contains(tableName, suffix) {
			return true
		}
	}

	return false
}

// CountRecords 统计表中的记录数，排除名称中包含 "copy" 的表
func (a *Analyzer) CountRecords(tables []string) (map[string]int64, error) {
	result := make(map[string]int64)

	for _, table := range tables {
		// 跳过名称中包含 "copy" 的表
		if strings.Contains(strings.ToLower(table), "copy") {
			slog.Info("跳过统计包含copy的表", "table", table)
			continue
		}

		query := fmt.Sprintf("SELECT COUNT(*) FROM `%s`", table)
		var count int64
		err := a.db.QueryRow(query).Scan(&count)
		if err != nil {
			slog.Warn("统计表记录数失败", "table", table, "error", err)
			continue
		}
		result[table] = count
	}

	return result, nil
}

// getStructureKey 生成表结构的唯一标识
func (a *Analyzer) getStructureKey(columns []database.Column) string {
	var parts []string
	for _, col := range columns {
		// 将列信息组合成字符串
		colStr := fmt.Sprintf("%s:%s:%s:%s:%s:%s",
			col.Field, col.Type, col.Null, col.Key, col.Default, col.Extra)
		parts = append(parts, colStr)
	}
	return strings.Join(parts, "|")
}

// 检查两个表结构是否相同
func (a *Analyzer) areStructuresEqual(struct1, struct2 []database.Column) bool {
	if len(struct1) != len(struct2) {
		return false
	}

	for i := range struct1 {
		if !reflect.DeepEqual(struct1[i], struct2[i]) {
			return false
		}
	}

	return true
}
